home *** CD-ROM | disk | FTP | other *** search
/ FM Towns: Free Software Collection 6 / FM Towns Free Software Collection 6.iso / t_os / book / src / bin.c < prev    next >
Text File  |  1993-07-08  |  4KB  |  186 lines

  1. /*
  2.  *  BinTree
  3. */
  4. #include    <stdio.h>
  5. #include    <stdlib.h>
  6. #include    <string.h>
  7. #include    <ctype.h>
  8. #include    <egb.h>
  9. #include    <mos.h>
  10. #include    "oaklib.h"
  11. #include    "book.h"
  12. #include    "lib.h"
  13.  
  14. #define HASH_MAX        16
  15. #define HASH(c)         ((c)&15)
  16.  
  17. typedef struct _DP {
  18.     struct _DP  *left;
  19.     struct _DP  *right;
  20.     int         len;
  21.     char        *str;
  22.     char        *snd;
  23. } DATA;
  24.  
  25. static DATA    *top[HASH_MAX] ;
  26.  
  27. extern  char   gwork[] ;
  28.  
  29. static  DATA    *search( char *str )
  30. {
  31.     int     cd ;
  32.     REGS    DATA    *dp ;
  33.  
  34.     dp = top[HASH(*str)] ;
  35.     while( dp != NULL )
  36.     {
  37.         if( ( cd = strncmp( str, dp->str, dp->len ) ) == 0 )
  38.             return dp ;
  39.         else if ( cd > 0 )
  40.             dp = dp->left ;
  41.         else
  42.             dp = dp->right ;
  43.     }
  44.     return NULL ;
  45. }
  46.  
  47. /*  指定の文字列の中に登録文字列があったら、読み上げる  */
  48.  
  49. #define X(x) ((x)*8+XMIN)
  50. #define CC   2
  51.  
  52. int     snd_str( int y, char *buf, int bytes )
  53. {
  54.     int     status = ERR + 1 ;
  55.     int     pos = 0 ;
  56.     int     n, xpos ;
  57.     int     flg_line = FALSE ;
  58.     DATA    *dp ;
  59.     char    *str = buf ;
  60.  
  61.     DSP_writePage( gwork, 0 ) ;
  62.     EGB_writeMode( gwork, 4 ) ;
  63.  
  64.     while( pos < bytes )
  65.     {
  66.         if( ( dp = search( str ) ) != NULL )
  67.         {
  68.             if( flg_line == FALSE ) /*  見つかったら、アンダーラインをひく  */
  69.             {
  70.                 dsp_box_clip( XMIN,y,    XMAX,y,    CC,CC,CC ) ;
  71.                 dsp_box_clip( XMIN,y+15, XMAX,y+15, CC,CC,CC ) ;
  72.                 flg_line = TRUE ;
  73.             }
  74.             xpos = calc_pos( buf, pos ) ;
  75.             dsp_box_clip( X(xpos),y+1, X(xpos+dp->len)-1,y+14, CC,CC,CC ) ;
  76.             status = snd_play( dp->snd ) ;
  77.             dsp_box_clip( X(xpos),y+1, X(xpos+dp->len)-1,y+14, CC,CC,CC ) ;
  78.             if( status == ERR )
  79.                 break ;
  80.  
  81.             n = dp->len ;
  82.         }
  83.         else if( iskanji(*str) && iskanji2(*(str+1)) )
  84.             n = 2 ;
  85.         else
  86.             n = 1 ;
  87.         str += n ;
  88.         pos += n ;
  89.     }
  90.     if( flg_line == TRUE )  /*  アンダーラインがあるなら、消す  */
  91.     {
  92.         dsp_box_clip( XMIN,y,    XMAX,y,    CC,CC,CC ) ;
  93.         dsp_box_clip( XMIN,y+15, XMAX,y+15, CC,CC,CC ) ;
  94.     }
  95.  
  96.     EGB_writeMode( gwork, 0 ) ;
  97.     DSP_writePage( gwork, 1 ) ;
  98.  
  99.     return( status ) ;
  100. }
  101.  
  102. static  DATA    *new_tree( char *str, char *snd )
  103. {
  104.     REGS    DATA    *dp ;
  105.     auto    int     cd ;
  106.     auto    DATA    *tp ;
  107.     auto    DATA    tmp ;
  108.  
  109.     cd = 1 ;
  110.     tmp.left = top[ HASH(*str) ] ;
  111.     dp = &tmp ;
  112.     for( ; ; )
  113.     {
  114.         if( cd > 0 ) {
  115.             if( dp->left == NULL )
  116.                 break;
  117.             dp = dp->left;
  118.         } else {
  119.             if( dp->right == NULL )
  120.                 break;
  121.             dp = dp->right;
  122.         }
  123.         if( (cd = strcmp(str,dp->str)) == 0 )
  124.             return dp;
  125.     }
  126.     if( ( tp = (DATA *)malloc( sizeof( DATA ) ) ) == NULL )
  127.         return NULL ;
  128.  
  129.     tp->left = tp->right = NULL;
  130.     tp->len = strlen(str);
  131.     tp->str = strdup(str);
  132.     tp->snd = strdup(snd);
  133.  
  134.     if( cd > 0 )
  135.         dp->left = tp;
  136.     else
  137.         dp->right = tp;
  138.  
  139.     top[ HASH(*str) ] = tmp.left ;
  140.  
  141.     return tp ;
  142. }
  143.  
  144. /*
  145.  *  onsei.dicを読み込んで、辞書を作っておく
  146.  *
  147.  *  辞書がない、辞書の内容が空である、などの場合はERRを返す
  148. */
  149.  
  150. int     init_tree( char *file )
  151. {
  152.     auto    FILE    *fp ;
  153.     auto    char    *str, *snd ;
  154.     auto    char    buf[BUFSIZ] ;
  155.     REGS    char    *p ;
  156.     auto    int     num = 0 ;
  157.  
  158.     if( ( fp = fopen( file, "r" ) ) == NULL )
  159.         return ERR ;
  160.     while( fgets( buf, BUFSIZ, fp ), !feof( fp ) )
  161.     {
  162.         if( buf[0] == '#' || buf[0] == '\n' )
  163.             continue ;
  164.         if( ( p = strchr( buf, '\n' ) ) != NULL )
  165.             *p = '\0' ;
  166.         p = buf ;
  167.         while( isspace(*p) ) p++;
  168.         str = p;
  169.         while( !isspace(*p) && *p != '\0' ) p++;
  170.         if( *p != '\0' )
  171.             *(p++) = '\0';
  172.         while( isspace(*p) ) p++;
  173.         snd = p;
  174.         if( *str != '\0' && *snd != '\0' &&
  175.              new_tree( str, snd ) == NULL )
  176.         {
  177.             fclose( fp ) ;
  178.             return ERR ;
  179.         }
  180.         num ++ ;        /*  登録したものの数  */
  181.     }
  182.     fclose( fp ) ;
  183.  
  184.     return ( num > 0 ) ? ERR+1 : ERR ;
  185. }
  186.